home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
L' Effet Pommier 3
/
L'Effet Pommier - Volume 03.iso
/
Programmation
/
gray image 2.1
/
vimage.cc
< prev
next >
Wrap
Text File
|
1995-05-30
|
29KB
|
884 lines
// This may look like C code, but it is really -*- C++ -*-
/*
************************************************************************
*
* Grayscale Image
*
* Verify the class image member functions and friends
*
* $Id: vimage.cc,v 2.0 1995/03/18 18:45:04 oleg Exp oleg $
*
************************************************************************
*/
#include "image.h"
#include "std.h"
#include <iostream.h>
#include <minmax.h>
static IMAGE Test_image(16,32,8); //(256,512,8);
/*
*----------------------------------------------------------------------
* Testing primitive operations and inquires
*/
static void test_primitive(void)
{
cout << "\n\nTest primitive image operations and inquires\n";
IMAGE image(Test_image);
cout << "\nInquires for the image like Test image";
cout << "\nNo of rows " << image.q_nrows();
cout << "\nNo of cols " << image.q_ncols();
cout << "\nDepth " << image.q_depth();
cout << "\nTotal no pixels " << image.q_npixels();
cout << "\nName '" << image.q_name() << "'";
cout << "\nThe following line is returned by image.info()\n";
image.info();
assert( image.q_npixels() == image.q_ncols() * image.q_nrows() );
cout << "\nDone\n\n";
}
// Verify the rowcol class
static void test_rowcol(void)
{
cout << "\n\nTest the rowcol class and operations on it\n";
const int row_const = 5, col_const = 32005;
{
cout << "\tVerify constructing the rowcol object from two integers\n";
rowcol pos1(row_const,col_const);
assert( pos1.row() == row_const && pos1.col() == col_const );
}
{
cout << "\tVerify assignment operations\n";
rowcol pos1(row_const,col_const);
rowcol pos2(-1,-1);
assert( pos2.row() != row_const && pos2.col() != col_const );
pos2 = pos1;
assert( pos2.row() == row_const && pos2.col() == col_const );
rowcol pos3(pos2);
assert( pos3.row() == row_const && pos3.col() == col_const );
pos3 = rowcol(col_const,row_const);
assert( pos3.col() == row_const && pos3.row() == col_const );
}
{
cout << "\tVerify comparisons\n";
rowcol pos1(row_const,col_const);
rowcol pos2(-1,-1);
assert( !(pos2 == pos1) );
pos2 = pos1;
assert( pos2 == pos1 );
assert( pos2 == rowcol(row_const,col_const) );
rowcol pos4(row_const,0);
assert( !(pos4 == pos1) );
rowcol pos5(0,col_const);
assert( !(pos5 == pos1) );
}
{
cout << "\tVerify shifting and offsetting operations\n";
rowcol pos1(row_const,col_const);
rowcol pos2(pos1);
assert( pos1 == pos2 );
assert( (pos1-pos2) == rowcol(0,0) );
assert( pos1 == pos2 );
pos1 -= pos2;
assert( pos1 == rowcol(0,0) );
assert( pos2 == rowcol(row_const,col_const) );
assert( (pos1+pos2) == pos2 );
assert( !(pos1 == pos2) );
pos1 += pos2;
assert( pos1 == pos2 );
assert( (pos1-rowcol(row_const,0)) == rowcol(0,col_const) );
pos1 -= rowcol(row_const,0);
assert( pos1 == rowcol(0,col_const) );
pos1 += rowcol(0,1);
assert( pos1 == rowcol(0,col_const+1) );
pos2 -= pos1;
assert( pos2 == rowcol(row_const,-1) );
assert( (pos1+pos2) == rowcol(row_const,col_const) );
pos1 += pos2;
assert( pos1 == rowcol(row_const,col_const) );
}
{
cout << "\tVerify scaling operations\n";
rowcol pos1(4,5);
rowcol pos2(pos1);
pos1 *= 1;
assert( pos1 == pos2 );
pos1 *= 4;
assert( pos1 == pos2 * 4 );
assert( pos1 == pos2 << 2 );
assert( pos1 >> 2 == pos2 );
pos2 += pos2;
pos2 += pos2;
assert( pos1 == pos2 );
}
cout << "\nDone\n\n";
}
/*
*----------------------------------------------------------------------
* Testing reading/writing a pixel and pixel modifications
*/
static void test_pixel_op()
{
const int pattern = 145;
register int i,j;
cout << "\n\nTest reading/writing pixels and pixel modifications\n";
cout << "Writing zeros ...\n";
for(i=0; i<Test_image.q_nrows(); i++)
for(j=0; j<Test_image.q_ncols(); j++)
Test_image(i,j) = 0;
verify_pixel_value(Test_image,0);
assert( Test_image == 0 );
cout << "Writing a pattern 0x" << hex << pattern << dec << "...\n";
for(i=0; i<Test_image.q_nrows(); i++)
for(j=0; j<Test_image.q_ncols(); j++)
Test_image(rowcol(i,j)) = pattern;
verify_pixel_value(Test_image,pattern);
assert( Test_image == pattern );
assert( Test_image > 0 && Test_image >= pattern );
assert( !(Test_image == 0) && Test_image != 0 );
assert( Test_image > pattern-1 && Test_image >= pattern-1 );
assert( Test_image < pattern+1 && Test_image <= pattern+1 );
assert( Test_image <= pattern && !(Test_image < pattern) );
assert( Test_image >= pattern && !(Test_image > pattern) );
cout << "Inverting the image, the pattern has to turn to " <<
hex << 0xff - pattern << "...\n";
Test_image.invert();
verify_pixel_value(Test_image,0xff - pattern);
cout << "Clearing the image ...\n";
Test_image.clear();
verify_pixel_value(Test_image,0);
assert( Test_image < pattern && Test_image <= pattern );
const int test_val = 0x7e;
cout << "Assigning the value " << hex << test_val
<< " to all the pixels...\n" << dec;
Test_image = test_val;
verify_pixel_value(Test_image,test_val);
cout << "Adding three...\n";
Test_image += 3;
verify_pixel_value(Test_image,test_val+3);
assure( Test_image > 0, "Negative pixel unexpected");
cout << "Subtracting " << 2*test_val << "...\n";
Test_image -= 2*test_val;
verify_pixel_value(Test_image,test_val+3-2*test_val);
assure( Test_image < 0, "Non-Negative pixel unexpected");
cout << "Subtracting " << -2*test_val+3 << "...\n";
Test_image -= -2*test_val+3;
verify_pixel_value(Test_image,test_val);
cout << "Set two lowest bits\n";
Test_image |= 0x03;
verify_pixel_value(Test_image,test_val | 0x03);
cout << "Reset two lowest bits\n";
Test_image &= 0xff - 0x03;
verify_pixel_value(Test_image,test_val & (0xff - 0x03));
cout << "Set the 2nd bit with XOR\n";
Test_image ^= 0x02;
verify_pixel_value(Test_image,test_val);
cout << "Multiply by 2\n";
Test_image *= 2;
verify_pixel_value(Test_image,2*test_val);
cout << "Multiply by 2 once more by shifting to the left\n";
Test_image <<= 1;
verify_pixel_value(Test_image,4*test_val);
cout << "Divide by 4 by shifting to the right\n";
Test_image >>= 2;
verify_pixel_value(Test_image,test_val);
cout << "If image >=0, then abs(image) should coincide with itself\n";
assert( Test_image >= 0 );
Test_image.abs();
verify_pixel_value(Test_image,test_val);
cout << "Assign image = -test_val and test image.abs()\n";
Test_image -= 2*test_val;
assert( Test_image < 0 );
Test_image.abs();
verify_pixel_value(Test_image,test_val);
{
cout << "Assign image = -test_val and test image.apply(abs)\n";
Test_image -= 2*test_val;
assert( Test_image < 0 );
class AbsImage : public PixelPrimAction {
void operation(GRAY& pixel) { pixel = abs((GRAY_SIGNED)pixel); }
public: AbsImage(void) {}
};
Test_image.apply(AbsImage());
verify_pixel_value(Test_image,test_val);
}
cout << "Assign image = -test_val and put down all negative pixels\n";
Test_image -= 2*test_val;
assert( Test_image < 0 );
Test_image.clip_to_intensity_range();
verify_pixel_value(Test_image,0);
cout << "Assign image = max_val+test_val and clip to the intensity region\n";
Test_image = test_val;
Test_image.clip_to_intensity_range();
verify_pixel_value(Test_image,test_val);
Test_image += (1<<Test_image.q_depth())-1;
Test_image.clip_to_intensity_range();
verify_pixel_value(Test_image,(1<<Test_image.q_depth())-1);
{
cout << "Check to see that PixelAction are executed row-wise" << endl;
class assign_pixels : public PixelAction {
const card test_im_nrows, test_im_ncols;
void operation(GRAY& pixel)
{
assert(nrows == test_im_nrows);
assert(ncols == test_im_ncols);
pixel = col + row*ncols;
}
public: assign_pixels(const IMAGE& im) :
test_im_nrows(im.q_nrows()), test_im_ncols(im.q_ncols()) {}
};
Test_image.apply(assign_pixels(Test_image));
class check_pixels : public PixelPrimAction {
GRAY curr_value;
void operation(GRAY& pixel) { assert(pixel == curr_value++); }
public: check_pixels(void) : curr_value(0) {}
};
Test_image.apply(check_pixels());
}
cout << "\nDone\n\n";
}
static void test_image_op()
{
const int pattern = 144;
cout << "\n\nTest binary image operations and comparisons\n";
cout << "Pattern value being used " << pattern <<
" (0x" << hex << pattern << dec << ")\n";
cout << "Allocation with assignment\n";
Test_image = pattern;
IMAGE im2 = Test_image; im2 = Test_image;
assure(Test_image == im2, "Non-identical images");
cout << "Assignment of one image to the other\n";
im2 += pattern;
Test_image = im2;
assure(Test_image==im2, "Non-identical images");
verify_pixel_value(Test_image,2*pattern);
cout << "Subtraction of two images\n";
im2 = pattern;
Test_image -= im2;
assure(Test_image==im2, "Non-identical images");
verify_pixel_value(Test_image,pattern);
assert(Test_image == pattern);
cout << "Addition of images\n";
Test_image += im2;
assure(!(Test_image==im2), "Identical images unexpected");
verify_pixel_value(Test_image,2*pattern);
#if 0
cout << "Addition of images through add() function\n";
add(Test_image,2,im2);
assure(!(Test_image==im2), "Identical images unexpected");
verify_pixel_value(Test_image,4*pattern);
cout << "Subtraction of images through add() function\n";
add(Test_image,-3,im2);
assure(Test_image==im2, "Non-identical images");
verify_pixel_value(Test_image,pattern);
cout << "Double only one pixel,(5,6), and perform operations to triple it\n";
Test_image(5,6) *= 2;
Test_image += im2;
add(Test_image,-3,im2);
Test_image += Test_image;
add(Test_image,3,im2);
compare(Test_image,im2,"Image with one pixel different and original");
#endif
cout << "Subtracting the image from itself\n";
Test_image -= Test_image;
verify_pixel_value(Test_image,0);
cout << "Set two lower bits\n";
Test_image = pattern; im2 = 0x03;
Test_image |= im2;
verify_pixel_value(Test_image,pattern | 0x03);
cout << "Reset two lowest bits\n";
im2.invert();
Test_image &= im2;
verify_pixel_value(Test_image,pattern & (0xff - 0x03));
cout << "Set the 2nd bit with XOR\n";
im2 = 0x02;
Test_image ^= im2;
verify_pixel_value(Test_image,pattern | 0x02);
cout << "OR with 0x13 followed by AND with 0x6d for non-uniform image\n";
Test_image = pattern; Test_image(4,5) += 5;
im2 = 0x13; Test_image |= im2; im2.invert(); Test_image &= im2;
im2 = pattern; im2(4,5) += 5;
im2 |= 0x13; im2 &= ~(0x13);
assure(Test_image == im2,"Pixel-by-pixel and image-by-image produced"
"different results");
cout << "XORing the image with itself\n";
Test_image ^= Test_image;
verify_pixel_value(Test_image,0);
#if 0
cout << "Add two images through shift_clip_add\n";
Test_image = pattern;
Test_image.shift_clip_add(rowcol(0,0),1,Test_image);
verify_pixel_value(Test_image,2*pattern);
im2 = pattern;
Test_image.shift_clip_add(rowcol(0,0),-2,im2);
verify_pixel_value(Test_image,0);
{
cout << "Change a single pixel through shift_clip_add\n";
Test_image = 2*pattern;
im2 = pattern;
rowcol rightbottom(Test_image.q_nrows()-1,Test_image.q_ncols()-1);
Test_image(rightbottom) += pattern; // Increment a pixel
assert( !(Test_image == 2*pattern) && !(Test_image != 2*pattern) );
Test_image.shift_clip_add(rightbottom,-1,im2); // and decrement it back
verify_pixel_value(Test_image,2*pattern); // in the other way
assert( Test_image == 2*pattern );
{
Test_image(0,0) -= pattern;
assert( !(Test_image == 2*pattern) && !(Test_image != 2*pattern) );
rowcol pos = rightbottom * (-1);
Test_image.shift_clip_add(pos,1,im2);
// Test_image.shift_clip_add(rightbottom * (-1),1,im2);
verify_pixel_value(Test_image,2*pattern);
assert( Test_image == 2*pattern );
}
}
{
cout << "Change a bottom right quadrant through shift_clip_add\n";
Test_image = 2*pattern;
im2 = pattern;
rowcol rightbottom(Test_image.q_nrows()-1,Test_image.q_ncols()-1);
rowcol center(Test_image.q_nrows()/2,Test_image.q_ncols()/2);
Test_image.rectangle(center,rightbottom) -= 2*pattern; // Decrement a block
assert( !(Test_image == 2*pattern) && !(Test_image != 2*pattern) );
Test_image.shift_clip_add(center,2,im2); // and increment it back
verify_pixel_value(Test_image,2*pattern); // in the other way
assert( Test_image == 2*pattern );
}
{
cout << "Change a part of the image through shift_clip_add\n";
Test_image = 3*pattern;
rowcol pos1(4,5);
rowcol pos2(Test_image.q_nrows()-2,Test_image.q_ncols()-3);
IMAGE im3 = Test_image.rectangle(pos1,pos2);
Test_image.rectangle(pos1,pos2) -= 3*pattern; // Decrement a block
assert( !(Test_image == 3*pattern) && !(Test_image != 3*pattern) );
assert( im3 == 3*pattern );
Test_image.shift_clip_add(pos1,1,im3); // and increment it back
verify_pixel_value(Test_image,3*pattern); // in the other way
assert( Test_image == 3*pattern );
}
#endif
cout << "\nDone\n\n";
}
/*
*------------------------------------------------------------------------
* Testing norm and scalar product calculations
*/
static void test_scalar_product()
{
const int pattern = 145;
cout << "\n\nTest the computation of the scalar product of two images\n";
cout << "Pattern value being used " << pattern;
int dim = (max(Test_image.q_nrows(),Test_image.q_ncols()) >> 1) << 1;
IMAGE imt(dim,dim,8), ims(dim,dim,8);
cout << "\nSquare image of size " << dim << " is being tested";
cout << "\nTesting by making the Haar (+ - - +) function and checking\n"
"its orthogonality with other Haar functions";
// Make the Haar (+ - - +) function
ims.square_of(dim/2,rowcol(0,0)) = pattern;
ims.square_of(dim/2,rowcol(0,dim/2)) = -pattern;
ims.square_of(dim/2,rowcol(dim/2,0)) = -pattern;
ims.square_of(dim/2,rowcol(dim/2,dim/2)) = pattern;
assert( ims != 0 && !(ims == 0) && !(ims == pattern) && !(ims != pattern) );
assert( !(ims >= pattern) && ims >= -pattern && ims <= pattern );
assert( !(ims > 0) && !(ims < 0) );
cout << "\nsum over ims " << sum_over(ims.square_of(dim,rowcol(0,0)));
imt = pattern;
cout << "\n Scalar product with Haar (+ + + +) function is " << ims * imt;
imt.square_of(dim/2,rowcol(0,0)) = -pattern;
imt.square_of(dim/2,rowcol(0,dim/2)) = -pattern;
imt.square_of(dim/2,rowcol(dim/2,0)) = pattern;
imt.square_of(dim/2,rowcol(dim/2,dim/2)) = pattern;
cout << "\n Scalar product with Haar (- - + +) function is " << imt * ims;
imt.square_of(dim/2,rowcol(0,0)) = -pattern;
imt.square_of(dim/2,rowcol(0,dim/2)) = pattern;
imt.square_of(dim/2,rowcol(dim/2,0)) = -pattern;
imt.square_of(dim/2,rowcol(dim/2,dim/2)) = pattern;
cout << "\n Scalar product with Haar (- + - +) function is " << ims * imt;
imt = ims;
cout << "\n Scalar product with Haar (+ - - +) function is " << imt * ims;
cout << "\n Theoretical value "
<< sqr(pattern * dim);
assure( imt * ims == sqr(pattern * dim), "There is discrepancy!" );
cout << "\nDone\n\n";
}
static void test_image_norms(void)
{
const int pattern = 154;
cout << "\n\nTest image norm computations\n";
Test_image.clear();
cout << "\nInitializing the image with the pattern " << pattern << "...\n";
Test_image = pattern;
cout << "\tChecking out the 1. image norm, which should be "
<< pattern * (double)Test_image.q_npixels() << "\n";
assert( Test_image.norm_1() == pattern * (double)Test_image.q_npixels() );
cout << "\tChecking out the 2. image norm, which should be "
<< pattern * pattern * (double)Test_image.q_npixels() << "\n";
assert( Test_image.norm_2_sqr() ==
sqr(pattern) * (double)Test_image.q_npixels() );
cout << "\tChecking out the 2. image norm is equal to the scalar product\n"
"\t\tof the image with itself\n";
assert( Test_image.norm_2_sqr() == Test_image * Test_image );
cout << "\tChecking out the inf image norm is equal to the pattern itself\n";
assert( Test_image.norm_inf() == pattern );
cout << "\nInitializing the image with the pattern " << pattern <<
"\n with a quater of it being set to " << -2*pattern << "\n";
Test_image = pattern;
int size = min(Test_image.q_ncols(),Test_image.q_nrows())/2;
Test_image.square_of(size,rowcol(0,0)) = -2*pattern;
assert( !(Test_image == pattern) && !(Test_image != pattern) );
assert( Test_image <= pattern && Test_image >= -2*pattern );
assert( !(Test_image > 0) && !(Test_image < 0) && Test_image != 0 );
cout << "\tChecking out the 1. image norm\n";
assert( Test_image.norm_1() == pattern * (double)Test_image.q_npixels()
+ pattern * size * size );
{
IMAGE im(Test_image);
im = Test_image;
im.abs();
assert( im.norm_1() == Test_image.norm_1() );
}
cout << "\tChecking out the 2. image norm\n";
assert( Test_image.norm_2_sqr() ==
sqr(pattern) * (double)Test_image.q_npixels() +
3 * sqr(pattern) * sqr(size) );
{
IMAGE im(Test_image); IMAGE im1(im);
im = pattern;
im.square_of(size,rowcol(0,0)) = -1;
im1 = im;
class SqrImage : public PixelPrimAction {
void operation(GRAY& pixel) { pixel = sqr((GRAY_SIGNED)pixel); }
public: SqrImage(void) {}
};
im1.apply(SqrImage());
assert( sum_over((Rectangle)im1) == im.norm_2_sqr() );
}
cout << "\tChecking out the 2. image norm is equal to the scalar product\n"
"\t\tof the image with itself\n";
assert( Test_image.norm_2_sqr() == Test_image * Test_image );
cout << "\tChecking out the inf image norm\n";
assert( Test_image.norm_inf() == 2*pattern );
cout << "\nChecking out that the image is equal to itself\n"
"(according to norms)\n";
assert( norm_1(Test_image,Test_image) == 0 );
assert( norm_2_sqr(Test_image,Test_image) == 0 );
assert( norm_inf(Test_image,Test_image) == 0 );
cout << "\nCheck the difference between the test images set as above"
"\nand the image with the uniform pattern\n";
IMAGE im1(Test_image);
im1 = pattern;
cout << "\tVerify the identity ||im1-im2|| = ||im2-im1||\n";
assert( norm_1(Test_image,im1) == norm_1(im1,Test_image) );
assert( norm_2_sqr(Test_image,im1) == norm_2_sqr(im1,Test_image) );
assert( norm_inf(Test_image,im1) == norm_inf(im1,Test_image) );
cout << "\tVerify the norm values\n";
assert( norm_1(Test_image,im1) == 3 * pattern * sqr(size) );
assert( norm_2_sqr(Test_image,im1) == sqr(3 * pattern) * sqr(size) );
assert( norm_inf(Test_image,im1) == 3 * pattern );
cout << "\nDone\n\n";
}
// Check out min/max finding operations
static void test_image_extrema(void)
{
const int pattern = 154;
cout << "\n\nTest finding extremum pixel values and image normalization\n";
{
cout << "\n\tExtrema of the zero image\n";
Test_image.clear();
Extrema extr(Test_image);
assert( extr.min() == 0 && extr.max() == 0 );
}
{
cout << "\tInitializing the image with the pattern " << pattern << "\n";
Test_image = pattern;
Extrema extr(Test_image);
assert( extr.min() == pattern && extr.max() == pattern );
}
{
cout << "\tSetting pixel (1,2) to 0\n";
Test_image(1,2) = 0;
Extrema extr(Test_image);
assert( extr.min() == 0 && extr.max() == pattern &&
extr.loc_min() == rowcol(1,2) );
assert( Test_image >= extr.min() && Test_image <= extr.max() );
}
{
cout << "\tSetting pixel (2,1) to 2*pattern = " << 2*pattern << "\n";
Test_image(2,1) = 2*pattern;
Extrema extr(Test_image);
assert( extr.min() == 0 && extr.max() == 2*pattern &&
extr.loc_min() == rowcol(1,2) && extr.loc_max() == rowcol(2,1) );
assert( Test_image >= extr.min() && Test_image <= extr.max() );
}
{
cout << "\tOffsetting by " << pattern << "\n";
Test_image -= pattern;
Extrema extr(Test_image);
assert( extr.min() == -pattern && extr.max() == pattern &&
extr.loc_min() == rowcol(1,2) && extr.loc_max() == rowcol(2,1) );
assert( Test_image >= extr.min() && Test_image <= extr.max() );
}
{
cout << "\tOffsetting by " << 2*pattern << "\n";
Test_image -= 2*pattern;
Extrema extr(Test_image);
assert( extr.min() == -3*pattern && extr.max() == -pattern &&
extr.loc_min() == rowcol(1,2) && extr.loc_max() == rowcol(2,1) );
assert( Test_image >= extr.min() && Test_image <= extr.max() );
}
cout << "\tNormalization ... \n";
Test_image = pattern;
Test_image.square_of(4,rowcol(2,1)) = -3*pattern;
Test_image.normalize_for_display();
Extrema extr(Test_image);
assert( extr.min() == 0 && extr.max() >= (1<<Test_image.q_depth())-2 );
assert( Test_image >= extr.min() && Test_image <= extr.max() );
cout << "\nDone\n\n";
}
// Test the histogram equalization
static void test_equalization(void)
{
cout << "\n\nTest the histogram equalization\n";
{
cout << "\tTest equalizing 16x16x8 full-gray scale image\n";
IMAGE full_gray(16,16,8);
register int i,j;
for(i=0; i<16; i++)
for(j=0; j<16; j++)
full_gray(i,j) = (i<<4) | j;
Extrema full_gray_extr(full_gray);
assert( full_gray_extr.min() == 0 && full_gray_extr.max() == 255 );
full_gray.equalize(128);
// After the equalization, the
// image should have (almost) the
// same span but have only even
// pixel values
Extrema full_gray_extr_eq(full_gray);
assert( full_gray_extr_eq.min() == 0 && full_gray_extr_eq.max() == 254 );
for(i=0; i<16; i++)
for(j=0; j<16; j++)
assert( (full_gray(i,j) & 1) == 0 );
}
{
cout << "\tAn image with a flat histogram should stay this way\n";
IMAGE test_im(16,16,8);
test_im.rectangle(rowcol(0,0),rowcol(15,3)) = 0;
test_im.rectangle(rowcol(0,4),rowcol(15,7)) = 80;
test_im.rectangle(rowcol(0,8),rowcol(15,11)) = 160;
test_im.rectangle(rowcol(0,12),rowcol(15,15)) = 255;
test_im.equalize(128);
IMAGE test_im_ethalon(test_im);
test_im_ethalon.rectangle(rowcol(0,0),rowcol(15,3)) = 31;
test_im_ethalon.rectangle(rowcol(0,4),rowcol(15,7)) = 94;
test_im_ethalon.rectangle(rowcol(0,8),rowcol(15,11)) = 158;
test_im_ethalon.rectangle(rowcol(0,12),rowcol(15,15)) = 222;
assert( test_im == test_im_ethalon );
}
#if 0
{
cout << "\tTest equalizing of uneven histogram\n";
IMAGE test_im(16,16,4);
test_im = 8; // Make a stripy image
register int i,j; // with very uneven histogram
for(i=0; i<8; i++) // (large peak at value 8)
for(j=0; j<16; j++)
test_im(i,j) = j;
test_im.print("before");
test_im.equalize(16);
test_im.print("after");
}
#endif
cout << "\nDone\n\n";
}
// Test expand/shrink operations
static void test_expand_shrink()
{
const int pattern = 154;
cout << "\n\nTest shrink/expand image operations\n";
{
cout << "\tExpansion/shrinking of the uniform image\n";
Test_image = pattern;
IMAGE blown_out(IMAGE::Expand,Test_image);
assert( blown_out.q_nrows() == 2*Test_image.q_nrows() );
assert( blown_out.q_ncols() == 2*Test_image.q_ncols() );
assert( blown_out.q_depth() == Test_image.q_depth() );
assert( blown_out == pattern );
IMAGE blown_shrunk(IMAGE::Shrink,blown_out);
assert( blown_shrunk == Test_image );
{
IMAGE im(Test_image);
im.coerce(Test_image);
assert( im == Test_image );
}
{
IMAGE im(Test_image.q_nrows()+1,Test_image.q_ncols()/2-1,
Test_image.q_depth());
im.coerce(Test_image);
verify_pixel_value(im,pattern);
}
{
IMAGE im(Test_image.q_nrows()/3,Test_image.q_ncols()*2,
Test_image.q_depth());
im.coerce(Test_image);
verify_pixel_value(im,pattern);
}
}
{
cout << "\tExpansion of the uniform image with a small stain\n";
Test_image = pattern;
Test_image(0,0) = 1;
Test_image(1,1) = 0;
IMAGE blown_out(IMAGE::Expand,Test_image);
assert( blown_out(1,1) == 1 );
assert( blown_out(3,3) == 0 );
class BlowImage : public LazyImage
{
const IMAGE& orig_image;
void fill_in(IMAGE& im) const
{
for(register int i=0; i<im.q_nrows(); i++)
for(register int j=0; j<im.q_ncols(); j++)
im(i,j) = orig_image(i/2,j/2);
}
public:
BlowImage(const IMAGE& image) :
LazyImage(2*image.q_nrows(),2*image.q_ncols(),image.q_depth()),
orig_image(image) {}
};
IMAGE another_blown_out = BlowImage(Test_image);
assert( another_blown_out == blown_out );
IMAGE yet_another_blown_out(another_blown_out);
yet_another_blown_out.clear();
yet_another_blown_out.coerce(Test_image);
assert( yet_another_blown_out == blown_out );
IMAGE blown_shrunk(IMAGE::Shrink,blown_out);
assert( blown_shrunk == Test_image );
blown_out.square_of(2,rowcol(0,0)) += pattern - 1;
blown_out.square_of(2,rowcol(2,2)) += pattern;
assert( blown_out == pattern );
}
{
cout << "\tShrinking the uniform image with small stains\n";
Test_image = pattern;
Test_image.square_of(2,rowcol(0,0)) = 1; Test_image(0,0) = 0;
Test_image.square_of(2,rowcol(2,0)) = 5; Test_image(3,1) = 0;
Test_image.square_of(2,rowcol(0,2)) = 0; Test_image(0,2) = 1;
Test_image.square_of(2,rowcol(0,4)) = 0; Test_image(1,5) = 7;
Test_image.square_of(2,rowcol(2,2)) = 1;
Test_image(2,2) = 0; Test_image(3,3) = 0;
IMAGE shrunk(IMAGE::Shrink,Test_image);
assert( shrunk(0,0) == 1 );
assert( shrunk(0,1) == 0 );
shrunk(0,0) += pattern - 1;
shrunk(1,0) += pattern - 4;
shrunk(0,1) += pattern;
shrunk(0,2) += pattern - 2;
shrunk(1,1) += pattern - 1;
assert( shrunk == pattern );
}
{
cout << "\tStretching/shrinking an image with vertical stripes\n";
class MakeVStripes : public PixelAction
{
GRAY pattern;
void operation(GRAY& pixel) { pixel = col & 1 ? pattern : 0; }
public: MakeVStripes(const GRAY _p) : pattern(_p) {}
};
Test_image.apply(MakeVStripes(pattern));
IMAGE shrunk(Test_image.q_nrows()/3+1,
Test_image.q_ncols()/2,Test_image.q_depth());
shrunk.coerce(Test_image);
verify_pixel_value(shrunk,pattern);
IMAGE vert_shrunk(Test_image.q_nrows()/3-1,
Test_image.q_ncols(),Test_image.q_depth());
vert_shrunk.coerce(Test_image);
assert( Test_image.rectangle(rowcol(0,0),
rowcol(Test_image.q_nrows()/3-2,
Test_image.q_ncols()-1))
== vert_shrunk );
IMAGE vert_stretched(Test_image.q_nrows()+7,
Test_image.q_ncols(),Test_image.q_depth());
vert_stretched.coerce(Test_image);
assert( vert_stretched.rectangle(rowcol(0,0),
rowcol(Test_image.q_nrows()-1,
Test_image.q_ncols()-1))
== Test_image );
}
{
cout << "\tStretching/shrinking an image with horizontal stripes\n";
class MakeHStripes : public PixelAction
{
GRAY pattern;
void operation(GRAY& pixel) { pixel = row & 1 ? pattern : 0; }
public: MakeHStripes(const GRAY _p) : pattern(_p) {}
};
Test_image.apply(MakeHStripes(pattern));
IMAGE shrunk(Test_image.q_nrows()/2,
Test_image.q_ncols()+7,Test_image.q_depth());
shrunk.coerce(Test_image);
verify_pixel_value(shrunk,pattern);
IMAGE hor_shrunk(Test_image.q_nrows(),
Test_image.q_ncols()/3-1,Test_image.q_depth());
hor_shrunk.coerce(Test_image);
assert( Test_image.rectangle(rowcol(0,0),
rowcol(Test_image.q_nrows()-1,
Test_image.q_ncols()/3-2))
== hor_shrunk );
IMAGE hor_stretched(Test_image.q_nrows(),
Test_image.q_ncols()+9,Test_image.q_depth());
hor_stretched.coerce(Test_image);
assert( hor_stretched.rectangle(rowcol(0,0),
rowcol(Test_image.q_nrows()-1,
Test_image.q_ncols()-1))
== Test_image );
}
cout << "\nDone\n";
}
/*
*------------------------------------------------------------------------
* The testing routing module
*/
main()
{
test_primitive();
test_rowcol();
test_pixel_op();
test_image_op();
test_scalar_product();
test_image_norms();
test_image_extrema();
test_equalization();
test_expand_shrink();
}